home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2.0 - Programmer's Utilities Power Pack / Delphi 2.0 Programmer's Utilities Power Pack.iso / s_to_z / tpack / working.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-09-15  |  8.0 KB  |  269 lines

  1. unit Working;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, StdCtrls, Buttons,
  8.   OkCore, PasUtils, ExtCtrls;
  9.  
  10. type
  11. {------------------------------------------------------------------------------}
  12. {TOkBoxForm defines the look the generic OkBox. Change this form or modify the
  13. look at runtime via TOk.OnActivate; Take care to keep the default events!
  14. attached to FormClose and ButtonClick; The Defaults are implemented at the end.}
  15.  
  16.   TWorkingMsgFormStop   = procedure(Sender: TObject;Var CanStop:Boolean) of object;
  17.  
  18.   TWorkingForm = class(tForm)
  19.     StopLabel: TLabel;
  20.     StopButton: TBitBtn;
  21.     procedure StopButtonClick(Sender: TObject);
  22.     procedure FormCloseQuery(Sender: TObject; var CanStop: Boolean);
  23.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  24.   private
  25.     { Private declarations }
  26.   protected
  27.     { Protected declarations }
  28.     fOkClose: Boolean;
  29.     fOnOkStop: TWorkingMsgFormStop;
  30.   public
  31.     { Public declarations }
  32.     property OkClose:Boolean read fOkClose write fOkClose;
  33.     property OnOkStop: TWorkingMsgFormStop read fOnOkStop write fOnOkStop;
  34.   published
  35.     { Published declarations }
  36.   end;
  37.  
  38. {------------------------------------------------------------------------------}
  39.  
  40.   TOkFormActivate = procedure(StopForm:TForm;StopLabel:TLabel;StopButton:TButton) of object;
  41.  
  42.   TWorkingMsg = class(TOk)
  43.     Form:  TWorkingForm;
  44.   private
  45.     { Private declarations }
  46.     fVisible:        Boolean;
  47.     fOnFormActivate: TOkFormActivate;  {used to setup form.}
  48.   protected
  49.     { Protected declarations }
  50.     function BusyCount(Add:ShortInt):Integer;
  51.     procedure   SetActive(Flag:Boolean);             override;
  52.     procedure   SetVisible(Flag:Boolean);            Virtual;
  53.     procedure   DoOkStart(Var CanStart:Boolean);     override;
  54.     function    FreezeFormHandle:HWND;               override;
  55.     procedure   SetCritical(Flag:Boolean);           override;
  56.   public
  57.     { Public declarations }
  58.     constructor Create(AOwner:TComponent);           override;
  59.     procedure   Reset;                               virtual;
  60.     procedure   OkStopHandler(Sender:TObject;Var CanStop:Boolean);
  61.  
  62.     function IsNotBusy:Boolean;
  63.     procedure BusyReset;
  64.     procedure BusyOn;
  65.     procedure BusyMsg(const Text:String);
  66.     procedure BusyOff;
  67.  
  68.   published
  69.     { Published declarations }
  70.     property Visible:     Boolean      read fVisible    write SetVisible default true;
  71.     property OnFormActivate: TOkFormActivate read fOnFormActivate write fOnFormActivate;
  72.   end;
  73.  
  74. {------------------------------------------------------------------------------}
  75.  
  76. implementation
  77.  
  78. {$R *.DFM}
  79.  
  80. {------------------------------------------------------------------------------}
  81. {TOkBoxUForm.  *Here* is the OkBox Form code which defines ESSENTIAL events.
  82. You can completely redefine the Form via Ok.OnActivate; Below are the
  83. things that have to happen on the Form and CancelButton}
  84.  
  85. procedure TWorkingForm.StopButtonClick(Sender: TObject);
  86. begin
  87.   If Assigned(fOnOkStop) then   {if a OnOkStop proc is defined, allow closing.}
  88.     fOnOkStop(Sender,fOkClose);
  89. end;
  90.  
  91. procedure TWorkingForm.FormCloseQuery(Sender: TObject; var CanStop: Boolean);
  92. begin
  93.   StopButtonClick(Sender);
  94.   CanStop:=fOkClose;      {Form Property can be reset via fOnOkStop proc}
  95. end;
  96.  
  97. procedure TWorkingForm.FormClose(Sender: TObject; var Action: TCloseAction);
  98. begin
  99.  { Action:=caFree;}   {can't free all the time; keep one instance up to reset.}
  100. end;
  101.  
  102. {------------------------------------------------------------------------------}
  103.  
  104. constructor TWorkingMsg.Create(AOwner:TComponent);
  105. begin
  106.   inherited create(AOwner);
  107.   fVisible:=true;
  108. end;
  109.  
  110. procedure TWorkingMsg.SetVisible(Flag:Boolean);
  111. {must be much stronger on memory issues?
  112.   just not call activate if not visible!}
  113. begin
  114.   if flag<>fVisible then begin
  115.     fVisible:=Flag;
  116.     if assigned(Form) then
  117.       Form.Visible:=Flag;
  118.     end;
  119. end;
  120.  
  121. procedure TWorkingMsg.SetActive(Flag:Boolean);
  122. begin
  123.   if Enabled and Flag<>Active then begin
  124.     inherited SetActive(Flag);
  125.     if not Active and assigned(Form) then  {do we have one?}
  126.       Form.hide{Close};
  127.     end;
  128. end;
  129.  
  130. procedure TWorkingMsg.SetCritical(Flag:Boolean);
  131. {OkTry can not be stopped when in a critical section}
  132. var
  133.   l:boolean;
  134. begin
  135.   if flag<>Critical then begin
  136.     inherited SetCritical(Flag);
  137.     if assigned(Form) then
  138.       Form.StopButton.Enabled:=not Critical;
  139.     end;
  140. end;
  141.  
  142. procedure TWorkingMsg.DoOkStart(Var CanStart:Boolean);
  143. begin
  144.   Inherited DoOkStart(CanStart);
  145.   if CanStart then begin
  146.     Application.CreateForm(TWorkingForm,Form);
  147.     Form.OnOkStop:=OkStopHandler;
  148.     Form.OkClose:=True;
  149.     if assigned(fOnFormActivate) then
  150.       fOnFormActivate(tForm(Form),Form.StopLabel,Form.StopButton);
  151.     if fVisible then begin
  152.       Form.Show;
  153.       Form.Update;
  154.       end;
  155.     end;
  156. end;
  157.  
  158. function TWorkingMsg.FreezeFormHandle:HWND;
  159. begin
  160.   result:=Form.Handle;
  161. end;
  162.  
  163. procedure TWorkingMsg.OkStopHandler(Sender:TObject;Var CanStop:Boolean);
  164. begin
  165.   if Critical then                {can not exit in a critical section!}
  166.     CanStop:=False               {let the user beware!}
  167.   else begin
  168.     Active:=False;  {try to turn off.. ancestor will now call user's CanCanel proc}
  169.     CanStop:=Stop; {if that proc concurs, we allow the OkBoxform to close}
  170.      {That's all. The Active Flag has already been set to false when we return}
  171.     end;
  172. end;
  173.  
  174. procedure TWorkingMsg.Reset;
  175. var                            {not done}
  176.   OrgOnOkStop: TOkOnOkStop;
  177.   OrgOkClose:  Boolean;
  178. {unconditional deactivate. very useful while setting up OkTryes. put a call
  179. on a button somewhere to allow you to break out of things regardless of what you
  180. coded! very helpful during development (to me anyway) it is not used inside here}
  181. begin
  182.   inherited Reset;
  183.   if assigned(Form) then  {do we have one?}
  184.     with Form do begin     {begin manual override <g>}
  185.       OnOkStop:=nil;            {no denying the exit this time}
  186.       OkClose:=True;          {manually allow Close-- that'll set the vars.}
  187.       end;
  188.   Active:=False;
  189.   if assigned(Form) then begin
  190.     Form.Free;
  191.     Form:=nil;
  192.     end;
  193. end;
  194.  
  195.  
  196.  
  197. {------------------------------------------------------------------------------}
  198. { BUSY..                                                                       }
  199. {------------------------------------------------------------------------------}
  200. {the following is a set of procs to manage telling the user that we're busy.}
  201. {in order to implement this well, we're tracking how often the box has been turned
  202. on and off, placing it and removing it as needed.}
  203.  
  204.  
  205. {this is a little out of context and would/could cause trouble when exceptions occour}
  206.  
  207.  
  208. function TWorkingMsg.BusyCount(Add:ShortInt):Integer;
  209. {keep track of how often we've been turned on.}
  210. {parameters used to combine get/set}
  211. const
  212.   Count:Integer=0;
  213.   c:TCursor=crDefault;
  214. begin
  215.   Count:=Count+Add;
  216.   if Count<=0 then begin
  217.     Count:=0;
  218.     Screen.Cursor:=c;
  219.     end
  220.   else
  221.     if Count=Add then begin {just turned on}
  222.       c:=Screen.Cursor;
  223.       Screen.Cursor:=crHourGlass;
  224.       end;
  225.   Result:=Count;
  226. end;
  227.  
  228. function TWorkingMsg.IsNotBusy:Boolean;
  229. {inquire about the box status and syncronize the counter if it's off}
  230. begin
  231.   Result:=Stop;
  232.   if Result then
  233.     if BusyCount(0)>0 then
  234.       BusyCount(-BusyCount(0));
  235. end;
  236.  
  237. procedure TWorkingMsg.BusyOn;
  238. {Turn it on anyway!! (resetting the box) and up the counter}
  239. begin
  240.   OkOn;
  241.   BusyCount(1);
  242. end;
  243.  
  244. procedure TWorkingMsg.BusyMsg(const Text:String);
  245. {could stall! this is why this functionality belongs into StopBox! and TOK!}
  246. begin
  247.   Form.StopLabel.Caption:=Text;
  248. end;
  249.  
  250. procedure TWorkingMsg.BusyOff;
  251. {turn off only when we're counting back to 0 and it's on in the second place}
  252. begin
  253.   if BusyCount(0)=1 then
  254.     if not IsNotBusy then
  255.       OkOff;
  256.   BusyCount(-1);
  257. end;
  258.  
  259. procedure TWorkingMsg.BusyReset;
  260. begin
  261.   if BusyCount(0)>0 then
  262.     BusyCount(-BusyCount(0));
  263.   BusyOff;
  264. end;
  265.  
  266.  
  267.  
  268. end.
  269.